from functools import partial
import timeit


class Person:
    def __init__(self, name: str, address: str, email: str) -> None:
        self.name = name
        self.address = address
        self.email = email



class PersonSlots:
    # tail python donot access attribute by __dict__
    __slots__ = "name", "address", "email"
    def __init__(self, name: str, address: str, email: str) -> None:
        self.name = name
        self.address = address
        self.email = email


def get_set_delete(person: Person | PersonSlots):
    person.address = "123 Main St"
    _ = person.address
    del person.address


def main():
    person = Person("AKW", "ZH", "2497744746@qq.com") 
    person_slots = PersonSlots("AKW", "ZH", "2497744746@qq.com")
    print(person.__dict__)
    person.hi = "hello"
    print(person.__dict__)
    # print(person_slots.__dict__)  # AttributeError: 'PersonSlots' object has no attribute '__dict__'. Did you mean: '__dir__'?
    # person_slots.hi = "hello" # AttributeError: 'PersonSlots' object has no attribute 'hi'
    # print(person_slots.__dict__)
    no_slots = min(timeit.repeat(partial(get_set_delete, person), number=1000000))
    slots = min(timeit.repeat(partial(get_set_delete, person_slots), number=1000000))
    print(f'No slots: {no_slots}')
    print(f'Slots: {slots}')
    print(f'Slots is {(no_slots / slots) / no_slots: .2%} times faster')


if __name__ == "__main__":
    main()

